package com.livepass.android.girlspicks.adapters;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.livepass.android.girlspicks.MyApplication;
import com.livepass.android.girlspicks.R;
import com.livepass.android.girlspicks.activities.PushCommentReplyActivity;
import com.livepass.android.girlspicks.models.Article;
import com.livepass.android.girlspicks.models.Comment;
import com.livepass.android.girlspicks.utils.GestureListener;
import com.livepass.android.girlspicks.utils.JSONParser;
import com.livepass.android.girlspicks.utils.Utilities;
import com.livepass.android.girlspicks.views.CustomProgressBar;

public class CommentAdapter extends BaseExpandableListAdapter {
	Comment comm;
	Activity context;
	ArrayList<Comment> listComments;
	Map<String, List<Comment>> listReplys;
	private Article mArticle;
	private int currentTouch = 0; //=1 is like, 2 is dislike

	private AsyncSetLike loaderLike;
	private EditText edtReply;
	private AsyncPostReply loaderPostReply;
	private AsyncSetReport loaderReport;

	public CommentAdapter(Activity context, List<Comment> listComments,
			Map<String, List<Comment>> listReplys, Article article) {
		this.context = context;
		// this.resourceID = resource;
		this.listComments = (ArrayList<Comment>) listComments;
		this.listReplys = listReplys;
		this.mArticle = article;
	}
	
	@Override
	public int getGroupCount() {
		return listComments.size();
	}

	@Override
	public int getChildrenCount(int groupPosition) {
		if (listReplys.size() > 0) {
			return listReplys.get(
					listComments.get(groupPosition).getCommentId()).size() + 1;
		} else {
			return 0;
		}
	}

	@Override
	public Comment getGroup(int groupPosition) {
		return listComments.get(groupPosition);
	}

	@Override
	public Comment getChild(int groupPosition, int childPosition) {
		if (childPosition < listReplys.get(
				listComments.get(groupPosition).getCommentId()).size()) {
			return listReplys.get(
					listComments.get(groupPosition).getCommentId()).get(
					childPosition);
		}
		return null;
	}

	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return childPosition;
	}

	@Override
	public boolean hasStableIds() {
		return true;
	}

	@Override
	public View getGroupView(final int groupPosition, final boolean isExpanded,
			View convertView, final ViewGroup parent) {
		// this.pos = position;
		TextView tvTime;
		TextView tvComment;
		TextView tvNumberOfReply;
		TextView tvNumberDisplay;
		LinearLayout llCommentButtonLike;
		LinearLayout llCommentButtonDislike;
		CustomProgressBar prgLikeDislike;
		if (convertView == null) {
			LayoutInflater inflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			// row = inflater.inflate(this.resourceID, null);
			convertView = inflater.inflate(R.layout.comment_list_item, parent,
					false);
			convertView.setDuplicateParentStateEnabled(false);
			prgLikeDislike = (CustomProgressBar) convertView
					.findViewById(R.id.prgComment);
			prgLikeDislike.setMax(200);
			//prgLikeDislike.setProgressColor(color1, color2);
		}else{
			prgLikeDislike = (CustomProgressBar) convertView
					.findViewById(R.id.prgComment);
		}
		
		//click items no expand
		final GestureDetector gestureDetector = new GestureDetector(new GestureListener(context));
		 convertView.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				//nothing
			}
		});
		 convertView.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				//for swipe left to right
				if (gestureDetector.onTouchEvent(event)) {
	                return true;
	            }
				return false;
			}
		});
		 
//		TextView tvUserName = (TextView) convertView
//				.findViewById(R.id.tvUserName);
		 tvTime = (TextView) convertView.findViewById(R.id.tvTime);
		 tvComment = (TextView) convertView
				.findViewById(R.id.tvComment);
		 tvNumberOfReply = (TextView) convertView
				.findViewById(R.id.tvNumberReply);
		 tvNumberDisplay = (TextView) convertView.findViewById(R.id.tvNumberDisplay);
		 llCommentButtonLike = (LinearLayout) convertView.findViewById(R.id.llCommentButtonLike);
		 llCommentButtonDislike = (LinearLayout) convertView.findViewById(R.id.llCommentButtonDislike);
		
		Comment comm = (Comment) getGroup(groupPosition);
		prgLikeDislike.setProgress(comm.getLikeCount(),comm.getDislikeCount());

		tvTime.setText(Utilities.convertToStandardTime(comm.getCreatedAt()));
		tvComment.setText(comm.getContent());
		
		tvNumberOfReply.setText(comm.getReplyCount());
		
		//set number of like and dislike above progress bar
		int num = comm.getLikeCount() - comm.getDislikeCount();
		 if(num > 0) {
			 tvNumberDisplay.setText("+"+num);
			 tvNumberDisplay.setTextColor(Color.parseColor("#f2616f"));
		 } else if(num == 0) {
			 tvNumberDisplay.setText("0");
			 tvNumberDisplay.setTextColor(Color.parseColor("#808080"));
		 } else {
			 tvNumberDisplay.setText(""+num);
			 tvNumberDisplay.setTextColor(Color.parseColor("#808080"));
		 }
		//set style for Comment by number of like or dislike
		if(num > 0) {
			tvComment.setTypeface(Typeface.DEFAULT_BOLD);
			if(num>100) {
				tvComment.setTextColor(Color.parseColor("#f2616f"));
			}
		} else {
			tvComment.setTypeface(Typeface.DEFAULT);
			tvComment.setTextColor(Color.parseColor("#666666"));
		}
		//set selected for like img or dislike img
		if(comm.getTypeLike() == 1) {
			llCommentButtonLike.setSelected(true);
			llCommentButtonDislike.setSelected(false);
		} else if(comm.getTypeLike() == 2) {
			llCommentButtonLike.setSelected(false);
			llCommentButtonDislike.setSelected(true);
		} else {
			llCommentButtonLike.setSelected(false);
			llCommentButtonDislike.setSelected(false);
		}

		// Reply button
		LinearLayout llReply = (LinearLayout) convertView
				.findViewById(R.id.llButtonReply);
		if (isExpanded) {
			llReply.setSelected(true);
		} else {
			llReply.setSelected(false);
		}
		// expand list reply
		llReply.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (!isExpanded) {
					((ExpandableListView) parent).expandGroup(groupPosition);
					v.setSelected(true);
				} else {
					((ExpandableListView) parent).collapseGroup(groupPosition);
					v.setSelected(false);
				}
			}
		});

		// Like comment button
		llCommentButtonLike.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Comment comm = (Comment) getGroup(groupPosition);
				if(comm.getTypeLike()==0 || comm.getTypeLike()==2){
					loaderLike = new AsyncSetLike(getGroup(groupPosition));
					loaderLike.execute("1");
					notifyDataSetChanged();
				} else {
					currentTouch = 1;
					loaderLike = new AsyncSetLike(getGroup(groupPosition));
					loaderLike.execute("0");
					notifyDataSetChanged();
				}
			}

		});

		// Dislike comment button
		llCommentButtonDislike.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Comment comm = (Comment) getGroup(groupPosition);
				if(comm.getTypeLike()==0 || comm.getTypeLike()==1){
					loaderLike = new AsyncSetLike(comm);
					loaderLike.execute("2");
					notifyDataSetChanged();
				} else {
					currentTouch = 2;
					loaderLike = new AsyncSetLike(comm);
					loaderLike.execute("0");
					notifyDataSetChanged();
				}
			}
		});

		// report
		TextView tvReport = (TextView) convertView
				.findViewById(R.id.tvCommentReport);
		tvReport.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				doReport(parent.getContext(), getGroup(groupPosition).getCommentId());
			}
		});

		return convertView;
	}

	@Override
	public View getChildView(final int groupPosition, final int childPosition,
			boolean isLastChild, View convertView, final ViewGroup parent) {
		
		LinearLayout llReplyInfo;
		LinearLayout llReplyButtonLikeDislike;
		//TextView tvReplyUserName;
		TextView tvReplyTime;
		TextView tvReply;
		TextView tvNumberDisplay;
		LinearLayout llPostReply;
		LinearLayout llReplyButtonLike;
		LinearLayout llReplyButtonDislike;
		CustomProgressBar prgReply;
		View row = convertView;
		// this.pos = position;
		if (row == null) {
			LayoutInflater inflater;
			inflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			// row = inflater.inflate(this.resourceID, null);
			row = inflater.inflate(R.layout.reply_list_item, parent, false);
			prgReply = (CustomProgressBar) row.findViewById(R.id.prgReply);
			prgReply.setMax(200);
			//prgLikeDislike.setProgressColor(color1, color2);
		}else{
			prgReply = (CustomProgressBar) convertView
					.findViewById(R.id.prgReply);
		}

		llReplyInfo = (LinearLayout) row.findViewById(R.id.llReplyInfo);
		llReplyButtonLikeDislike = (LinearLayout) row.findViewById(R.id.llReplyButtonLikeDislike);
		//tvReplyUserName = (TextView) row.findViewById(R.id.tvReplyUserName);
		tvReplyTime = (TextView) row.findViewById(R.id.tvReplyTime);
		tvReply = (TextView) row.findViewById(R.id.tvReply);
		edtReply = (EditText) row.findViewById(R.id.edtReply);
		llPostReply = (LinearLayout) row.findViewById(R.id.llPostReply);
		tvNumberDisplay = (TextView) row.findViewById(R.id.tvNumberDisplay);
		llReplyButtonLike = (LinearLayout) row.findViewById(R.id.llReplyButtonLike);
		llReplyButtonDislike = (LinearLayout) row.findViewById(R.id.llReplyButtonDislike);
		
		final Comment re = (Comment) getChild(groupPosition, childPosition);
		if (re != null) {

			//tvReplyUserName.setText(re.getUserId());
			tvReplyTime.setText(Utilities.convertToStandardTime(re.getCreatedAt()));
			tvReply.setText(re.getContent());
			
			prgReply.setProgress(re.getLikeCount(), re.getDislikeCount());
			
			//set number of like and dislike above progress bar
			int num = re.getLikeCount() - re.getDislikeCount();
			 if(num > 0) {
				 tvNumberDisplay.setText("+"+num);
				 tvNumberDisplay.setTextColor(Color.parseColor("#f2616f"));
			 } else if(num == 0) {
				 tvNumberDisplay.setText("0");
				 tvNumberDisplay.setTextColor(Color.parseColor("#808080"));
			 } else {
				 tvNumberDisplay.setText(""+num);
				 tvNumberDisplay.setTextColor(Color.parseColor("#808080"));
			 }
			 
			//set style for Comment by number of like or dislike
			if(num > 0) {
				tvReply.setTypeface(Typeface.DEFAULT_BOLD);
				if(num>100) {
					tvReply.setTextColor(Color.parseColor("#f2616f"));
				}
			} else {
				tvReply.setTypeface(Typeface.DEFAULT);
				tvReply.setTextColor(Color.parseColor("#666666"));
			}
			//set selected for like img or dislike img
			if(re.getTypeLike() == 1) {
				llReplyButtonLike.setSelected(true);
				llReplyButtonDislike.setSelected(false);
			} else if(re.getTypeLike() == 2) {
				llReplyButtonLike.setSelected(false);
				llReplyButtonDislike.setSelected(true);
			} else {
				llReplyButtonLike.setSelected(false);
				llReplyButtonDislike.setSelected(false);
			}
		}

		// Like reply button
		llReplyButtonLike.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if(re.getTypeLike()==0 || re.getTypeLike()==2) {
					loaderLike = new AsyncSetLike(getChild(groupPosition, childPosition));
					loaderLike.execute("1");
					notifyDataSetChanged();
				} else {
					loaderLike = new AsyncSetLike(getChild(groupPosition, childPosition));
					loaderLike.execute("0");
					currentTouch = 1;
					notifyDataSetChanged();
				}
			}

		});

		// Dislike button
		llReplyButtonDislike.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if(re.getTypeLike()==0 || re.getTypeLike()==1) {
					loaderLike = new AsyncSetLike(getChild(groupPosition, childPosition));
					loaderLike.execute("2");
					notifyDataSetChanged();
				} else {
					loaderLike = new AsyncSetLike(getChild(groupPosition, childPosition));
					loaderLike.execute("0");
					currentTouch = 2;
					notifyDataSetChanged();
				}
			}
		});

		// Set visible for EditText Reply
		if (childPosition == this.getChildrenCount(groupPosition) - 1) {
			llPostReply.setVisibility(View.VISIBLE);
			llReplyInfo.setVisibility(View.GONE);
			tvReply.setVisibility(View.GONE);
			llReplyButtonLikeDislike.setVisibility(View.GONE);
		} else {
			llPostReply.setVisibility(View.GONE);
			llReplyInfo.setVisibility(View.VISIBLE);
			tvReply.setVisibility(View.VISIBLE);
			llReplyButtonLikeDislike.setVisibility(View.VISIBLE);
		}

		// report
		TextView tvReport = (TextView) row.findViewById(R.id.tvReplyReport);
		tvReport.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				doReport(parent.getContext(), getChild(groupPosition, childPosition).getCommentId());
			}
		});

		//post reply
		edtReply.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				
				Intent intent = new Intent(context,
						PushCommentReplyActivity.class);
				intent.putExtra(MyApplication.WHERE, MyApplication.REPLY);
				comm = (Comment) getGroup(groupPosition);
				Bundle bun = new Bundle();
				bun.putSerializable("article", mArticle);
				intent.putExtras(bun);
				context.startActivityForResult(intent, MyApplication.REPLY);
			}
		});

		return row;
	}

	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == MyApplication.REPLY) {
			if (resultCode == Activity.RESULT_OK) {
				String commentString = data.getStringExtra("reply");
				//edtReply.setText(commentString);
				loaderPostReply = new AsyncPostReply(comm, commentString);
				loaderPostReply.execute();
				notifyDataSetChanged();
			}
		}
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return true;
	}

	/**
	 * 
	 * @param c
	 * @param
	 */
	public void doReport(final Context c, final String _id) {
		AlertDialog.Builder builder = new AlertDialog.Builder(c);
		// Add the buttons
		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				loaderReport = new AsyncSetReport();
				loaderReport.execute(_id);
			}
		});
		builder.setNegativeButton("キャンセル",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						// User cancelled the dialog
					}
				});
		// Set other dialog properties
		builder.setMessage("このコメントは不適切と 判断して通報しますか？");
		builder.setTitle("通報する");

		// Create the AlertDialog
		builder.create().show();
	}

	private class AsyncSetLike extends	AsyncTask<String, Void, Integer> {
		Comment mComment;

		public AsyncSetLike(Comment comment) {
			mComment = comment;
		}

		@Override
		protected Integer doInBackground(String... params) {

			int res = -1;
			Map<String, String> param = new LinkedHashMap<String, String>();
			param.put("id", "girlspicks");
			param.put("secret", "UCzCRQAAAIBVDBPwLuaV8o9mu");
			param.put("comment_id", mComment.getCommentId());
			param.put("client_id", MyApplication.USER_ID);
			param.put("type", params[0]);

			JSONObject jsonObject = null;
			try {
				jsonObject = Utilities.doPostRequest(
						"http://girlspicks.co/api/set_like", param);
				res = jsonObject.getInt("data");
			} catch (ClientProtocolException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}
			return res;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Integer result) {

			if (result != -1) {
				if(result == 0){
					if(currentTouch == 1) {//current touch is like
						mComment.setLikeCount(mComment.getLikeCount() - 1);
					} else {//current touch is dislike
						mComment.setDislikeCount(mComment.getDislikeCount() - 1);
					}
					mComment.setTypeLike(0);
					notifyDataSetChanged();
				} else if(result == 1){
					mComment.setLikeCount(mComment.getLikeCount() + 1);
					if(mComment.getTypeLike() == 2) {
						mComment.setDislikeCount(mComment.getDislikeCount() - 1);
					}
					mComment.setTypeLike(1);
					notifyDataSetChanged();
				} else if(result == 2) {
					mComment.setDislikeCount(mComment.getDislikeCount() + 1);
					if(mComment.getTypeLike() == 1) {
						mComment.setLikeCount(mComment.getLikeCount() - 1);
					}
					mComment.setTypeLike(2);
					notifyDataSetChanged();
				}
			} else {
				if(currentTouch == 1) {//current touch is like
					Toast.makeText(context,	"An unexpected error has occurred when like.",
							Toast.LENGTH_SHORT).show();
				} else {
					Toast.makeText(context,	"An unexpected error has occurred when dislike.",
							Toast.LENGTH_SHORT).show();
				}
			}
		}
	}
	
	private class AsyncPostReply extends AsyncTask<String, Void, String> {
		Comment mComment;
		String mTextReply;
		
		public AsyncPostReply(Comment comment, String textReply) {
			mComment = comment;
			mTextReply = textReply;
		}

		@Override
		protected String doInBackground(String... params) {
			String replyId = null;
			//post comment
			Map<String, String> param = new LinkedHashMap<String, String>();
			param.put("id", "girlspicks");
			param.put("secret", "UCzCRQAAAIBVDBPwLuaV8o9mu");
			param.put("article_id", mComment.getArticleId());
			param.put("parent_id", mComment.getCommentId());
			param.put("client_id", MyApplication.USER_ID);
			param.put("content", mTextReply);
			
			JSONObject jsonObject = null;
			JSONParser parser = new JSONParser();
			try {
				jsonObject = Utilities.doPostRequest("http://girlspicks.co/api/set_comment", param);
				replyId = parser.parserPostComment(jsonObject);
			} catch (ClientProtocolException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}			
			return replyId;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			//llLoading.setVisibility(View.VISIBLE);
		}

		@Override
		protected void onPostExecute(String result) {
			if(result != null) {
				//get current time
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
				String currentTime = format.format(System.currentTimeMillis());
				//create reply obj
				Comment reply = new Comment();
				reply.setArticleId(mComment.getArticleId());
				reply.setCommentId(result);
				reply.setClientId(MyApplication.USER_ID);
				reply.setContent(mTextReply);
				reply.setCreatedAt(currentTime);
				reply.setUpdatedAt(currentTime);
				reply.setIsDeleted("0");
				reply.setLikeCount(0);
				reply.setDislikeCount(0);
	
				listReplys.get(mComment.getCommentId()).add(reply);
				mComment.setReplyCount(""+listReplys.get(mComment.getCommentId()).size());
				notifyDataSetChanged();
			} else {
				Toast.makeText(context,
						"An unexpected error has occurred when reply",
						Toast.LENGTH_SHORT).show();
			}
			//llLoading.setVisibility(View.GONE);
		}
	}
	
	private class AsyncSetReport extends	AsyncTask<String, Void, Integer> {

		@Override
		protected Integer doInBackground(String... params) {

			int re = 1;
			Map<String, String> param = new LinkedHashMap<String, String>();
			param.put("id", "girlspicks");
			param.put("secret", "UCzCRQAAAIBVDBPwLuaV8o9mu");
			param.put("comment_id", params[0]);
			param.put("client_id", MyApplication.USER_ID);

			JSONObject jsonObject = null;
			try {
				jsonObject = Utilities.doPostRequest(
						"http://girlspicks.co/api/set_report", param);
				re = jsonObject.getInt("status");
			} catch (ClientProtocolException e1) {
				e1.printStackTrace();
				return re;
			} catch (IOException e1) {
				e1.printStackTrace();
				return re;
			} catch (JSONException e) {
				e.printStackTrace();
				return re;
			}
			return re;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Integer result) {

			if (result == 0) {
				Toast.makeText(context, "Thanks for report", Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(context,
						"An unexpected error has occurred when report",
						Toast.LENGTH_SHORT).show();
			}
		}
	}
}
